package cn.kwq.project_manger.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.kwq.project_manger.exception.CodeErrorException;
import cn.kwq.project_manger.pojo.QUser;
import cn.kwq.project_manger.pojo.User;
import cn.kwq.project_manger.pojo.dto.WYU_Dto;
import cn.kwq.project_manger.repostitory.UserRepository;
import cn.kwq.project_manger.service.LoginService;
import cn.kwq.project_manger.utils.AesUtils;
import cn.kwq.project_manger.utils.WechatUtils;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.ParseException;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    LoginWyuSystemImpl wyuLogin;
    @Autowired
    UserRepository userRepository;
    @Autowired
    JPAQueryFactory jpaQueryFactory;
    @Autowired
    WechatUtils wechatUtils;

    @Autowired
    AesUtils AES;


    @Override
    @Transactional(rollbackForClassName = "Exception.class")
    public User loginByWYU(String token, String code) throws IOException, ParseException, CodeErrorException {
        String openId = wechatUtils.getOpenId(code);

        WYU_Dto wyuDto = wyuLogin.getMessageByWYUsys(token);
        log.info(wyuDto.getName()+"登录教务系统成功");
        // DONE: 2022/11/6 通过openid查询数据库，有记录就登录，没记录就插入记录作为注册
        //此处构建query dsl的q对象
        QUser user = QUser.user;
        User loginOne = jpaQueryFactory
                .selectFrom(user)
                .from(user)
                .where(user.openid.eq(AES.S2AES(openId)))
                .fetchOne();
        //为空时注册返回不为空时直接返回
        if (loginOne==null) {
            log.info(wyuDto.getName()+"开始注册");
            //注册
            User register = User
                    .builder()
                    .nickName("未设置")
                    .userName(wyuDto.getName())
                    .stuNum(wyuDto.getStuNum())
                    .major(wyuDto.getMajor())
                    .institute(wyuDto.getInstitute())
                    .grade(wyuDto.getGrade())
                    .WYUclass(wyuDto.getWYUclass())
                    //加密存储
                    .openid(AES.S2AES(openId))
                    .build();
            userRepository.register(register);
            return jpaQueryFactory
                    .selectFrom(user)
                    .from(user)
                    .where(user.openid.eq(AES.S2AES(openId)))
                    .fetchOne();
        } else {
            //DONE:  2022/11/9 1:00 如果用户存在，检查教务系统学生信息是否有变更,变更了就更新信息(通过openid)
            if (WyuSysChange(wyuDto,loginOne)){
            log.info(AES.S2AES(openId));
                jpaQueryFactory.update(user)
                        .set(user.userName, wyuDto.getName())
                        .set(user.major, wyuDto.getMajor())
                        .set(user.institute,wyuDto.getInstitute() )
                        .set(user.WYUclass,wyuDto.getWYUclass() )
                        .set(user.grade,wyuDto.getGrade() )
                        .set(user.stuNum,wyuDto.getStuNum())
                        .where(user.openid.eq(AES.S2AES(openId)))
                        //执行更新
                        .execute();
                return userRepository.findById(loginOne.getId()).get();
            }else {
                return loginOne;
            }
        }
    }

    /**
     * 检查学生信息是否有变更
     * @param wyuDto
     * @return
     */
    private boolean WyuSysChange(WYU_Dto wyuDto,User userOne) {
        //少了一个信息时候也去更新（说明解绑了）
        if (    userOne.getStuNum()==null||
                userOne.getUserName()==null||
                userOne.getMajor()==null||
                userOne.getInstitute()==null||
                userOne.getWYUclass()==null||
                userOne.getGrade()==null

        ){
            return true;
        }


        if (    !wyuDto.getStuNum().equals(userOne.getStuNum()) ||
                !wyuDto.getName().equals(userOne.getUserName()) ||
                !wyuDto.getMajor().equals(userOne.getMajor()) ||
                !wyuDto.getInstitute().equals(userOne.getInstitute()) ||
                !wyuDto.getWYUclass().equals(userOne.getWYUclass())||
                !wyuDto.getGrade().equals(userOne.getGrade())
        ){
            //和数据库不同时就会变更
            return true;
        }else {
            return false;
        }
    }

}
